﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using MotoGame.Estados.Fases.Fase1;
using MotoGame.Core;

namespace MotoGame.Estados.Jogo
{
    /// <summary>
    /// Toda a fase 1
    /// </summary>
    class Fase1 : EstadoBase
    {
        Moto moto1;
        Song musica;
        SpriteFont arial;
        GameWindow Window;

        bool firstTimeMusic = true;

        Fundo cenario;

        IList<Plataforma> plataformas;
        IList<Fundo> fundos;
        //IList<Chao> chao; 
        CollisionDetector collisionDetector;
        
        public Fase1(ContentManager Content, GameWindow Window)
            :base(Content, Window)
        {
            this.Window = Window;

            moto1 = new Moto(Content, this.Window);

            musica = Content.Load<Song>("Sounds/Musics/music");

            arial = Content.Load<SpriteFont>("arial");

            fundos = new List<Fundo>();
            Fundo nuvens = new Fundo(Content.Load<Texture2D>("Fases/Fase1/Textures/nuvens"), Window);
            nuvens.VelocidadeRelativaX = 0.25f;
            fundos.Add(nuvens);
            
            Fundo montanhas = new Fundo(Content.Load<Texture2D>("Fases/Fase1/Textures/montanhas"), Window);
            montanhas.VelocidadeRelativaX = 0.75f;
            fundos.Add(montanhas);

            cenario = new Fundo(Content.Load<Texture2D>("Fases/Fase1/Textures/cenario"), Window);
            cenario.VelocidadeRelativaX = 1;
            fundos.Add(cenario);
            

            plataformas = new List<Plataforma>();

            plataformas.Add(new Plataforma(Content, Window, new Vector2(200, 365)));
            plataformas.Add(new Plataforma(Content, Window, new Vector2(450, 200)));

            collisionDetector = new CollisionDetector();
            collisionDetector.Sprites.Add(moto1);

            foreach (var plataforma in plataformas)
            {
                collisionDetector.Sprites.Add(plataforma);
            }


            collisionDetector.OnHit += (sender, args) => { 
                Window.Title = args.First + " bateu em " + args.Last; 
            };
        }

        public override void Update(GameTime gameTime)
        {
            if (firstTimeMusic)
            {
                //MediaPlayer.Play(musica);
                firstTimeMusic = false;
            }

            UpdateInput();
            collisionDetector.Update(gameTime);

            moto1.Update();

            // Ajusta a posicao da moto na tela e atualiza os demais objetos de acordo

            //Moto saindo pela direita.
            if(moto1.Posicao.X > Window.ClientBounds.Width * 2/3 && !cenario.AtRight)
            {
                moto1.Posicao = new Vector2(Window.ClientBounds.Width * 2 / 3, moto1.Posicao.Y);
                UpdateScene(gameTime, new Vector2(moto1.velocidade.X, 0));
            }

            //Moto saindo pela esquerda.
            if (moto1.Posicao.X < Window.ClientBounds.Width * 1 / 3 && !cenario.AtLeft)
            {
                moto1.Posicao = new Vector2(Window.ClientBounds.Width * 1 / 3, moto1.Posicao.Y);
                UpdateScene(gameTime, new Vector2(-moto1.velocidade.X, 0));
            }

            //Moto saindo por baixo.
            if (moto1.Posicao.Y > Window.ClientBounds.Height * 2 / 3 && !cenario.AtBottom)
            {
                moto1.Posicao = new Vector2(moto1.Posicao.X, Window.ClientBounds.Height * 2 / 3);
                UpdateScene(gameTime, new Vector2(0, moto1.velocidade.Y));
            }

            //Moto saindo por cima.
            if (moto1.Posicao.Y < Window.ClientBounds.Height * 1 / 3 && !cenario.AtTop)
            {
                moto1.Posicao = new Vector2(moto1.Posicao.X, Window.ClientBounds.Height * 1 / 3);
                UpdateScene(gameTime, new Vector2(0, -moto1.velocidade.Y));
            }
        }

        protected virtual void UpdateScene(GameTime gameTime, Vector2 aux)
        {

            foreach (var plataforma in plataformas)
            {
                plataforma.Update(gameTime, aux);
            }

            foreach (var fundo in fundos)
            {
                fundo.Update(gameTime, aux);
            }
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach (var fundo in fundos)
            {
                fundo.Draw(gameTime, spriteBatch);
            }

            moto1.Draw(gameTime, spriteBatch);


            foreach (var plataforma in plataformas)
            {
                plataforma.Draw(gameTime, spriteBatch);
            }

            spriteBatch.DrawString(arial, "Pontos: " + moto1.pontos, new Vector2(10, 10), Color.Red);
        }

        protected virtual void UpdateInput()
        {
            if (Game1.teclado_atual.IsKeyDown(Keys.E) && Game1.teclado_anterior.IsKeyUp(Keys.E))
            {
                Game1.StateManager.GoTo(Game1.Estado.EASTER);
            }

            // input da moto
            if (Game1.mouse_atual.LeftButton == ButtonState.Pressed)
            {
                moto1.MoveTo(Game1.mouse_atual.X, Game1.mouse_atual.Y);
            }

            if (Game1.teclado_atual.IsKeyDown(Keys.Right))
            {
                moto1.MoveRight();
            }
            if (Game1.teclado_atual.IsKeyDown(Keys.Left))
            {
                moto1.MoveLeft();
            }
            if (Game1.teclado_atual.IsKeyDown(Keys.Up))
            {
                moto1.MoveUp();
            }
            if (Game1.teclado_atual.IsKeyDown(Keys.Down))
            {
                moto1.MoveDown();
            }
        }
    }
}
